package de.bastian.hinterleitner.adaptersviews;

import java.util.ArrayList;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.RectF;
import android.graphics.Shader;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.widget.LinearLayout;
import de.bastian.hinterleitner.tools.Constants;
import de.bastian.hinterleitner.tools.Entry;
import de.hijacksoft.wyc.R;

/**
 *
 * @author basti
 */
public class Diagram extends View{

	/**
	 * list with removed seperators
	 */
    ArrayList<Entry> list = new ArrayList<Entry>();
    /**
     * fullList with all seperators
     */
    ArrayList<Entry> fullList = new ArrayList<Entry>();
    boolean drawText = false;
    Point mouse = new Point(0,0);
    private final String TAG = "WatchYourCash_Diagram";
    public boolean animating = false;
    private Context context;
    
    public Diagram(Context context) {
        super(context);
        this.context = context;
        this.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, 240));
    }
    
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch(event.getAction()){
            case MotionEvent.ACTION_DOWN:
            	if(event.getY()<getHeight())drawText = true;
                break;
            case MotionEvent.ACTION_UP:
            	onClick(event);
                drawText = false;
                break;
            case MotionEvent.ACTION_MOVE:
            	if(event.getY()<getHeight())drawText = true;
            	else drawText = false;
                break;
        }
        if(event.getY()<getHeight()){
    		mouse = new Point((int)event.getX(),(int)(getHeight()/3));
        }
        invalidate();
        // action_move tracking workaround:
        if(event.getAction() == MotionEvent.ACTION_DOWN)return true;
        else return super.onTouchEvent(event);
    }
    
    public void onExternalTouch(MotionEvent event){
    	mouse = new Point((int)event.getX(),(int)(getHeight()/3));
    	if(event.getAction() == MotionEvent.ACTION_UP){
    		if(drawText)onClick(event);
    		drawText = false;
    	}
    	invalidate();
    }
    
    private void onClick(MotionEvent event) {
		if(list.size()>0){
	        int i = (int)(mouse.x*list.size()/getWidth());
	        if(i<0 || i>=list.size())return;
	        onItemClicked(fullList.indexOf(list.get(i)));
		}
	}

    /**
     * hook when an item in the diagram is clicked
     * @param position the position of the item in the list
     */
    public void onItemClicked(int position){
    	
    }
    
	@Override
    protected void onDraw(Canvas c) {
        super.onDraw(c);
        Paint p = new Paint();
        p.setColor(Color.WHITE);
        p.setAntiAlias(true);
        
        c.drawRect(new RectF(0,0,getWidth(),getHeight()), p);

        // get the biggest amount:
        float max = 0;
        for(Entry e : list){
        	double val = e.getValueAs(context.getString(R.string.currency), context);
            if(Math.abs(val)>max && val!=Double.MIN_VALUE){
                max = (float)Math.abs(val);
            }
        }
        
        // draw grid:
        p.setColor(Color.argb(50, 0, 0, 0));
        for(int i=0;i<list.size();i+= Math.floor((1+list.size()/50))){
        	c.drawLine((float)(i*getWidth()/list.size()),
    	                0,
    	                (float)(i*getWidth()/list.size()),
    	                getHeight(), p);
        }
        
        int plus = (int)(getHeight()*100/max);
        if(max<=1)plus = (int)((getHeight()/10)/max);
        if(max<=10)plus = (int)(getHeight()/max);
        if(max<=100)plus = (int)(getHeight()*10/max);
        if(max>10000)plus = (int)(getHeight()*1000/max);
        
        for(int i=0;i<getHeight();i+=plus){
        	c.drawLine(0,getHeight()-i,getWidth(),getHeight()-i,p);
        }
        
        // draw background of touched field:
        if(drawText && list.size()>0){
            int i = (int)(mouse.x*list.size()/getWidth());
            
            p.setColor(Color.LTGRAY);
            
            c.drawRect(new RectF(
                    (float)(i*getWidth()/list.size())-1,
                    0,
                    (float)((i+1)*getWidth()/list.size()),
                    (float)(getHeight())), p);
        }

        p.setAlpha(255);
        for(int i=0;i<list.size();i++){
        	double value = list.get(i).getValueAs(context.getString(R.string.currency), context);
            double val = Math.abs(value);
            if(list.get(i).getId()==Constants.ID_SEPERATOR){
            	p.setShader(new LinearGradient((float)(i*getWidth()/list.size()), 0, (float)((i+1)*getWidth()/list.size()), 0, Color.rgb(225,225,225), Color.rgb(255, 255, 255), Shader.TileMode.MIRROR));
            }else if(value>=0){
                p.setShader(new LinearGradient((float)(i*getWidth()/list.size()), 0, (float)((i+1)*getWidth()/list.size()), 0, Color.rgb(150, 220, 175), Color.rgb(100, 220, 125), Shader.TileMode.MIRROR));
            }else {
                p.setShader(new LinearGradient((float)(i*getWidth()/list.size()), 0, (float)((i+1)*getWidth()/list.size()), 0, Color.rgb(220, 175, 150), Color.rgb(220, 125, 100), Shader.TileMode.MIRROR));
            }
            if(list.get(i).getId()==Constants.ID_SEPERATOR){
            	c.drawRect(new RectF(
    	                (float)(i*getWidth()/list.size()),
    	                (float)(0),
    	                (float)((i+1)*getWidth()/list.size()-1),
    	                (float)(getHeight())), p);
            }else{
            	
            	c.drawRect(new RectF(
    	                (float)(i*getWidth()/list.size()),
    	                (float)(getHeight()-getHeight()*val/max),
    	                (float)((i+1)*getWidth()/list.size()-1),
    	                (float)(getHeight())), p);
            }
            p.setShader(null);
        }
        
        p.setColor(Color.BLACK);
        c.rotate(-90);
        for(int i=0;i<list.size();i++){
            float size = .8f*getWidth()/list.size();
            if(size>20)size=20;
            float abstand = (getWidth()/list.size()-size)/2;
            p.setTextSize(size);
            c.drawText(list.get(i).getName(), -getHeight()+abstand, (float)((i+1)*getWidth()/list.size()-abstand), p);
        }
        
        c.rotate(90);
        
        if(drawText && list.size()>0){
            int i = (int)(mouse.x*list.size()/getWidth());
            
            if(i<0 || i>=list.size())return;
            
            String text = list.get(i).getName();
            
            p.setTextSize(20);
            
            float textSize = p.measureText(text);
            
            p.setColor(Color.BLACK);
            
            float left = (i+.5f)*getWidth()/list.size()-textSize/2;
            float top = mouse.y-p.getTextSize();
            float right = (i+.5f)*getWidth()/list.size()+textSize/2;
            float bottom = mouse.y;
            
            float borderSize = 2;
            
            RectF txt = new RectF(left-p.getTextSize()*0.5f, top-p.getTextSize()*0.5f, right+p.getTextSize()*0.5f, bottom+p.getTextSize()*0.5f);
            RectF border = new RectF(left-p.getTextSize()*0.5f-borderSize, top-p.getTextSize()*0.5f-borderSize, right+p.getTextSize()*0.5f+borderSize, bottom+p.getTextSize()*0.5f+borderSize);
            
            c.drawRoundRect(border,p.getTextSize()*0.5f,p.getTextSize()*0.5f, p);
            c.drawArc(new RectF(left+textSize/2-p.getTextSize()-borderSize*2,bottom-borderSize,left+textSize/2+p.getTextSize()+borderSize*2,bottom+p.getTextSize()*2+borderSize*2), 225, 90, true, p);
            
            p.setColor(Color.WHITE);
            c.drawRoundRect(txt,p.getTextSize()*0.5f,p.getTextSize()*0.5f, p);
            c.drawArc(new RectF(left+textSize/2-p.getTextSize(),bottom,left+textSize/2+p.getTextSize(),bottom+p.getTextSize()*2), 225, 90, true, p);
            
            p.setColor(Color.BLACK);
            c.drawText(text, left, bottom, p);
        }
    }
    
    @SuppressWarnings("unchecked")
	private ArrayList<Entry> removeSeperators(ArrayList<Entry> list){
    	list = (ArrayList<Entry>) list.clone();
    	for(int i=0;i<list.size();i++){
    		if(list.get(i).getId()==Constants.ID_SEPERATOR){
    			list.remove(i);
    			i--;
    		}
    	}
    	return list;
    }
    
    public void setItems(ArrayList<Entry> list){
        this.list = removeSeperators(list);
        this.fullList = list;
    }
    
    public ArrayList<Entry> getItems(){
        return list;
    }
}
